/*
 * BPlusTreeFixed.h
 *
 *  Created on: Nov 28, 2012
 *      Author: Federico Orquera
 */

#ifndef BPLUSTREEFIXED_H_
#define BPLUSTREEFIXED_H_

#include "bplusfilehandler/BPlusTreeFile.h"
#include "BPlusTreeTemplate.h"

/**
 * La tira cuando se usa el constructor viejo
 */

class BPlusTreeConstructorException: public std::exception {
	virtual const char* what() const throw () {
		return "El constructor se encuentra deprecated!!";
	}
};

/**
 * La tira cuando se hace un update sobre una key que no existe
 */

class BPlusTreeUpdateError: public std::exception {
	virtual const char* what() const throw () {
		return "El registro que se quiere actualizar no existe.";
	}
};

/**
 *	Una clase que  junta el file handler y el arbol templeteado
 *	en una sola clase para un manejo mas comodo
 */

class BPlusTreeFixed: public BPlusTreeTemplate< DTRkey_t, DTRvalue_t, keyComparator_func > {
public:

	/**
	 * Tira una excepcion para que no lo usen!
	 * @param newHandler
	 */

	BPlusTreeFixed(HandlerInterface* newHandler):BPlusTreeTemplate(newHandler){
		throw BPlusTreeConstructorException();
	}

	/**
	 * Constructor por los mismos parametros del file handler
	 * @param filename 	String del archivo que guarda la estructura del arbol
	 * @param blockSize	El tamaño en bytes de los nodos del arbol
	 * @param trunc		Si es true, crea un archivo nuevo independientemente de que exista anteriormente.
	 */

	BPlusTreeFixed(const string& filename, size_t blockSize = 0, bool trunc = false):
		BPlusTreeTemplate( new BPlusTreeFile(filename, blockSize, trunc) ){}

	virtual ~BPlusTreeFixed(){
		delete this->handler;
	}

	/**
	 * Insert al arbol por key y value
	 * @param key	La key del registro
	 * @param value	El value del registro
	 */

	void InsertRegister( const DTRkey_t& key, const DTRvalue_t& value ){
		register_ptr registro( new LeafRegister_t( key, value ) );
		BPlusTreeTemplate< DTRkey_t, DTRvalue_t, keyComparator_func >::InsertRegister( registro );
	}

	/**
	 * Insert con la interfaz vieja donde se pasa un shared_ptr al registro
	 * @param registro shared_ptr al registro
	 */

	void InsertRegister( const register_ptr& registro ){
		BPlusTreeTemplate< DTRkey_t, DTRvalue_t, keyComparator_func >::InsertRegister( registro );
	}

	/**
	 * Update para la Inverted List Position de un key
	 * @param key		Key del registro a modificar
	 * @param position	Valor de la Inverted List Position
	 */

	void UpdateRegister( const DTRkey_t& key, const InvertedListPosition& position ){

		DTRvalue_t value;

		auto queryResult = this->SearchRegister(key);

		if(!queryResult.valid) throw BPlusTreeUpdateError();

		value = queryResult.result->getValue();

		value.m_invertedListPosition = position;

		register_ptr registro( new LeafRegister_t( key, value ) );

		BPlusTreeTemplate< DTRkey_t, DTRvalue_t, keyComparator_func >::UpdateRegister( registro );

	}

	/**
	 * Update con la interfaz vieja donde se pasa un shared_ptr al registro
	 * @param registro registro shared_ptr al registro
	 */

	void UpdateRegister( const register_ptr& registro ){
		BPlusTreeTemplate< DTRkey_t, DTRvalue_t, keyComparator_func >::UpdateRegister( registro );
	}

};

#endif /* BPLUSTREEFIXED_H_ */
